#include "DataParser_lines.h"
#include <QRegularExpression>

using namespace std;

// 1.实现虚函数
bool DataParser_post::readFile(const QString& qFullName) {
	QFileInfo fileInfo(qFullName);
	QString qfielPath = fileInfo.absolutePath();
	QString qfileBaseName = fileInfo.baseName();
	QString suffix = fileInfo.suffix().toLower();
	bool readSuccessed = false;
	if (suffix == "lines" )
		readSuccessed = read_post(qFullName);
	else
		return false;
	return readSuccessed;

}

bool DataParser_post::saveFile(const QString& qFullName){

	return true;
}
bool DataParser_post::saveFileAs(const QString& qFullName) {
	return true;
}
void DataParser_post::setMinMax() {
	// 获取最大最小的数字
	double x1 = m_nums.num1, y1 = m_nums.num2;
	double x2 = m_nums.num3, y2 = m_nums.num4;
	if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2)) return;
	double minX = min(x1, x2);
	double minY = min(y1, y2);
	double maxX = max(x1, x2);
	double maxY = max(y1, y2);

	if (m_data->minPt.x() < 0 && m_data->minPt.y() < 0 && m_data->maxPt.x() < 0 && m_data->maxPt.y() < 0) {  //初始化
		m_data->minPt.setX(minX);
		m_data->minPt.setY(minY);
		m_data->maxPt.setX(maxX);
		m_data->maxPt.setY(maxY);
	}
	else {
		m_data->minPt.setX(min(m_data->minPt.x(), minX));
		m_data->minPt.setY(min(m_data->minPt.y(), minY));
		m_data->maxPt.setX(max(m_data->maxPt.x(), maxX));
		m_data->maxPt.setY(max(m_data->maxPt.y(), maxY));
	}
}

// 2.数据处理（公有）

bool DataParser_post::read_post(const QString& qFullName) {
	QFile file(qFullName);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
		return false;
	}

	QTextStream in(&file);
	QString line;
	vector<vector<numbers>> wireCoordinates;
	vector<vector<vector<numbers>>> obsCoordinates;
	vector<vector<numbers>> fixlinesCoordinates;
	vector<vector<numbers>> locklinesCoordinates;
	vector<vector<double>> gapCoordinates;
	vector<vector<double>> spacesCoordinate;
	vector<int> diffInfo_dirsCoordinates;
	bool inWire = false;
	bool inObss = false;
	bool inFixLines = false;
	bool inLockLines = false;
	bool inGap = false;
	bool inSpaces = false;
	bool inOther = false;
	bool in_diffInfo_dir = false;

	while (!in.atEnd()) {
		line = in.readLine();
		// 如果获取到的行没有数据，是空行，则跳过
		if (line.isEmpty())
			continue;
		if (isSymbol(line, wiresSymbol)) {
			inWire = true;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			wireCoordinates.push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, obss_Symbol)) {
			inWire = false;
			inObss = true;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			if (obsCoordinates.size() < wireCoordinates.size() || obsCoordinates.size() == 0) {
				obsCoordinates.push_back(vector<vector<numbers>>());
			}
			obsCoordinates.back().push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, miterSymbol)) {
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			continue;
		}
		else if (isSymbol(line, fixLiSymbol)) {
			inWire = false;
			inObss = false;
			inFixLines = true;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			fixlinesCoordinates.push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, lockLSymbol)) {
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = true;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			locklinesCoordinates.push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, diGapSymbol)) {
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = true;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			gapCoordinates.push_back(vector<double>());
			continue;
		}
		else if (isSymbol(line, spcssSymbol)) {
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = true;
			in_diffInfo_dir = false;
			inOther = false;
			spacesCoordinate.push_back(vector<double>());
			continue;
		}
		else if (isSymbol(line, diDirSymbol)) {
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = true;
			inOther = false;
			continue;
		}
		else if (line.startsWith("#")) {
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = true;
			continue;
		}
		if (inWire) {
			int rst = parseLine(line, m_nums);
			m_nums.num5 = defaltWidth_;
			setMinMax();
			if (rst >= 4)
				wireCoordinates.back().push_back(m_nums);
			else
				continue;
		}
		else if (inObss) {
			int rst = parseLine(line, m_nums);
			setMinMax();
			if (rst >= 4)
				obsCoordinates.back().back().push_back(m_nums);
			else
				continue;
		}
		else if (inFixLines) {
			int rst = parseLine(line, m_nums);
			if (rst >= 4)
				fixlinesCoordinates.back().push_back(m_nums);
			else
				continue;
		}
		else if (inLockLines) {
			int rst = parseLine(line, m_nums);
			if (rst >= 4)
				locklinesCoordinates.back().push_back(m_nums);
			else
				continue;
		}
		else if (inGap) {
			int rst = parseLine(line, m_nums);
			if (rst == 1) {
				if (m_nums.num1 == 0) m_nums.num1 = 1;
				gapCoordinates.back().push_back(m_nums.num1);
			}
		}
		else if (inSpaces) {
			int rst = parseLine(line, m_nums);
			if (rst == 1) {
				if (m_nums.num1 == 0) m_nums.num1 = 1;
				spacesCoordinate.back().push_back(m_nums.num1);
			}
		}
		else if (in_diffInfo_dir) {
			int rst = parseLine(line, m_nums);
			if (rst == 1) {
				if (m_nums.num1 == 0) m_nums.num1 = 1;
				diffInfo_dirsCoordinates.push_back(m_nums.num1);
			}
		}
		// 如果读取完了一组后处理数据，但是该组数据缺少一些数据，为了每组数据的完整性，需要将其余数据赋默认值
		fillBlankData(wireCoordinates, obsCoordinates, fixlinesCoordinates, locklinesCoordinates, gapCoordinates, spacesCoordinate, diffInfo_dirsCoordinates, 1);
	}
	int wireSize = (int)wireCoordinates.size();
	while (wireCoordinates.size() < wireSize || obsCoordinates.size() < wireSize || fixlinesCoordinates.size() < wireSize || locklinesCoordinates.size() < wireSize
		|| gapCoordinates.size() < wireSize || spacesCoordinate.size() < wireSize || diffInfo_dirsCoordinates.size() < wireSize) {
		fillBlankData(wireCoordinates, obsCoordinates, fixlinesCoordinates, locklinesCoordinates, gapCoordinates, spacesCoordinate, diffInfo_dirsCoordinates, 0);
	}
	file.close();
	// hugSegments_数据赋值
	for (const auto& one_wire : wireCoordinates) {
		if (one_wire.empty())
			break;
		m_data->m_wires.emplace_back(vector<LineUI>());
		for (const auto& nums : one_wire) {
			LineUI line(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4));
			line.width = nums.num5;
			m_data->m_wires.back().push_back(line);
		}
	}

	// Obs数据赋值
	for (const auto& obss : obsCoordinates) {
		m_data->m_polygonss.emplace_back(vector<vector<LineUI>>());
		for (const auto& obs : obss) {
			m_data->m_polygonss.back().emplace_back(vector<LineUI>());
			if (obs.empty()) continue;
			double minx = obs.front().num1, miny = obs.front().num2;
			double maxx = minx, maxy = miny;
			for (const auto& nums : obs) {
				m_data->m_polygonss.back().back().emplace_back(LineUI(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4)));
				minx = min(minx, min(nums.num1, nums.num3));
				miny = min(miny, min(nums.num2, nums.num4));
				maxx = max(maxx, max(nums.num1, nums.num3));
				maxy = max(maxy, max(nums.num2, nums.num4));
			}
			m_data->obssMinMaxXY.push_back({ minx, maxx, miny, maxy });
		}
	}
	// fixLines_数据赋值
	for (const auto& one_fixline : fixlinesCoordinates) {
		m_data->fixLines_.push_back(vector<LineUI>());
		if (one_fixline.empty()) continue;
		for (const auto& nums : one_fixline) {
			m_data->fixLines_.back().push_back(LineUI(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4)));
		}
	}
	// lockLines_数据赋值
	for (const auto& one_lockline : locklinesCoordinates) {
		m_data->lockLines_.push_back(vector<LineUI>());
		if (one_lockline.empty()) continue;
		for (const auto& nums : one_lockline) {
			m_data->lockLines_.back().push_back(LineUI(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4)));
		}
	}
	// diffGaps_数据赋值
	for (const auto& one_gap : gapCoordinates) {
		m_data->diffGaps_.push_back(vector<double>());
		if (one_gap.empty()) continue;
		for (const auto& gap : one_gap) {
			m_data->diffGaps_.back().push_back(gap);
		}
	}
	//spaces数据赋值
	for (const auto& one_space : spacesCoordinate) {
		m_data->spaces_.push_back(vector<double>());
		if (one_space.empty()) continue;
		for (const auto& space : one_space) {
			m_data->spaces_.back().push_back(space);
		}
	}
	// diffInfo_dirs数据赋值
	for (const auto& dir : diffInfo_dirsCoordinates) {
		int dir_side = dir == 2010 ? 2 : dir;
		m_data->diffInfo_dirs.push_back(dir_side);
	}
	return true;
}
int DataParser_post::parseLine(QString& line, numbers& nums)
{
	if (line.startsWith("0(Pt")) {
		// 支持科学计数法的正则表达式
		QRegularExpression regex(R"(0\(Pt1\s*([\d.+\-Ee]+)\s+([\d.+\-Ee]+)\)\(Pt2\s*([\d.+\-Ee]+)\s+([\d.+\-Ee]+)\)(?:\(width\s*([\d.+\-Ee]+)\))?)");
		QRegularExpressionMatch match = regex.match(line);

		if (match.hasMatch()) {
			bool ok1, ok2, ok3, ok4, ok5;
			nums[0] = match.captured(1).toDouble(&ok1);
			nums[1] = match.captured(2).toDouble(&ok2);
			nums[2] = match.captured(3).toDouble(&ok3);
			nums[3] = match.captured(4).toDouble(&ok4);

			if (ok1 && ok2 && ok3 && ok4) {
				if (!match.captured(5).isEmpty()) {
					nums[4] = match.captured(5).toDouble(&ok5);
					return ok5 ? 5 : 4;
				}
				return 4;
			}
		}
	}
	QTextStream lineStream(&line);
	int valuesRead = 0;

	while (!lineStream.atEnd() && valuesRead < 5) {
		lineStream >> nums[valuesRead];
		valuesRead++;
	}
	return valuesRead;
}

void DataParser_post::fillBlankData(vector<vector<numbers>>& wireCoordinates,
	vector<vector<vector<numbers>>>& obsCoordinates,
	vector<vector<numbers>>& fixlinesCoordinates,
	vector<vector<numbers>>& locklinesCoordinates,
	vector<vector<double>>& gapCoordinates,
	vector<vector<double>>& spacesCoordinate,
	vector<int>& diffInfo_dirsCoordinates, int add) {
	// add = 1，表示在读取数据内部，add = 0表示已经完成所有数据的读取
	if ((int)obsCoordinates.size() < (int)wireCoordinates.size() - add) {				// 1.补全obs
		obsCoordinates.emplace_back(vector<vector<numbers>>());
	}
	if ((int)fixlinesCoordinates.size() < (int)wireCoordinates.size() - add) {			// 2.补全fixlines
		fixlinesCoordinates.emplace_back(vector<numbers>());
	}
	if ((int)locklinesCoordinates.size() < (int)wireCoordinates.size() - add) {			// 3.补全locklines
		locklinesCoordinates.emplace_back(vector<numbers>());
	}
	if ((int)gapCoordinates.size() < (int)wireCoordinates.size() - add) {				// 4.补全gaps
		gapCoordinates.emplace_back(vector<double>());
	}
	if ((int)spacesCoordinate.size() < (int)wireCoordinates.size() - add) {				// 5.补全spaces
		spacesCoordinate.emplace_back(vector<double>());
	}
	if ((int)diffInfo_dirsCoordinates.size() < (int)wireCoordinates.size() - add) {		// 6.补全diffInfo_dirsCoordinates
		diffInfo_dirsCoordinates.emplace_back(2010);
	}
}

